﻿namespace FFF.Test
{
    using System;
    using System.Collections.Generic;
    using System.IdentityModel.Tokens.Jwt;
    using System.IO;
    using System.Linq;
    using System.Threading.Tasks;
    using Abp.Runtime.Caching;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.Http;
    using FFF.Test.Application.AppServices.PublicService.Sessions;
    using FFF.Test.Application.Repositories.FW;
    using FFF.Test.Entity.FW.View;
    using FFF.Test.Util.Consts;
    using Ydm.Extensions;

    /// <summary>
    /// ydm中间间
    /// </summary>
    public class YdmSessionMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly IHostingEnvironment _env;
        private readonly IFWUserRepository _fWUserRepository;
        private readonly ICacheManager _cacheManager;

        /// <summary>
        /// Initializes a new instance of the <see cref="YdmSessionMiddleware"/> class.
        /// 权限的中间件处理
        /// </summary>
        /// <param name="next">下一个节点</param>
        /// <param name="env">环境变量</param>
        /// <param name="fWUserRepository">用户仓储</param>
        /// <param name="cacheManager">缓存服务</param>
        public YdmSessionMiddleware(
            RequestDelegate next,
            IHostingEnvironment env,
            IFWUserRepository fWUserRepository,
            ICacheManager cacheManager
            )
        {
            this._next = next;
            this._env = env;
            this._fWUserRepository = fWUserRepository;
            this._cacheManager = cacheManager;
        }

        /// <summary>
        /// 处理context的请求
        /// </summary>
        /// <param name="context">context请求</param>
        /// <returns>任务</returns>
        public async Task Invoke(HttpContext context)
        {
            ViewFWUser viewUser = context.Session.GetUserInfo();

            // 如果是ajax 那么从jwtcam中获取用户的ID（header一般用于app小程序等其他第三方的）
            if (viewUser == null && this.IsAjaxRequest(context))
            {
                string sessiodId = context.User.Claims.FirstOrDefault(d => d.Type == JwtRegisteredClaimNames.Sid)?.Value;

                // 如果为空那么就从header中获取
                if (sessiodId.IsNullOrEmpty())
                {
                    sessiodId = context.Request.Headers[AppConfigConsts.UserSessionId];
                }

                if (!sessiodId.IsNullOrEmpty())
                {
                    ViewFWUser view = await this._cacheManager
                      .GetCache(CacheAppConsts.UserStoreCache)
                      .GetAsync(sessiodId, () => this._fWUserRepository.GetUserInfoByGUID(new Guid(sessiodId))
                      );

                    if (view != null)
                    {
                        context.Session.SetUserInfo(view);
                    }
                }
            }

            await this._next(context);
        }

        private bool IsAjaxRequest(HttpContext context)
        {
            string header = context.Request.Headers["X-Requested-With"];
            return "XMLHttpRequest".Equals(header, StringComparison.OrdinalIgnoreCase);
        }

        private bool IsPageRequest(HttpContext context)
        {
            string header = context.Request.Headers["Accept"];
            if (header == null)
            {
                return false;
            }
            else
            {
                return header.Contains("text/html");
            }
        }

    }
}
